﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace Ruction
{
    /// <summary>Provides basic logic for collections.</summary>
    /// <typeparam name="T">The type of collection.</typeparam>
    public abstract class BaseObjectCollection<T> : List<T>, INotifyCollectionChanged, INotifyPropertyChanged where T : class
    {
        #region Events

        #region CollectionChanged
        /// <summary>Raised when the contents of the collection have changed.</summary>
        public event NotifyCollectionChangedEventHandler CollectionChanged;
        #endregion CollectionChanged

        #region PropertyChanged
        /// <summary>Raised when a property on this instance changes.</summary>
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion PropertyChanged

        #endregion Events

        #region Methods

        #region Add
        /// <summary>Adds aitem to the collection.</summary>
        /// <param name="item">The item to be added to the collection.</param>
        new public void Add(T item)
        {
            base.Add(item);
            OnCollectionChanged();
        }
        #endregion Add

        #region Clear
        /// <summary>Clears all items from the collection.</summary>
        new public void Clear()
        {
            base.Clear();
            OnCollectionChanged();
        }
        #endregion Clear

        #region Contains
        /// <summary>Indicates if the collection contains a item.</summary>
        /// <param name="item">The item for which existance will be checked.</param>
        new public bool Contains(T item)
        {
            return base.Contains(item);
        }
        #endregion Contains

        #region CopyTo
        /// <summary>Copies the items from this collection to an array.</summary>
        /// <param name="array">The destination array.</param>
        /// <param name="arrayIndex">The starting zero-based index in the destination array at which item will be inserted.</param>
        new public void CopyTo(T[] array, int arrayIndex)
        {
            base.CopyTo(array, arrayIndex);
        }
        #endregion CopyTo

        #region IndexOf
        /// <summary>Gets the index of the specific item in the collection.</summary>
        /// <param name="item">The item for which the index will be returned.</param>
        new public int IndexOf(T item)
        {
            return base.IndexOf(item);
        }
        #endregion IndexOf

        #region Insert
        /// <summary>Inserts a items at a specific index in the collection.</summary>
        /// <param name="index">The index at which the item will be inserted.</param>
        /// <param name="item">The item to be inserted.</param>
        new public void Insert(int index, T item)
        {
            base.Insert(index, item);
            OnCollectionChanged();
        }
        #endregion Insert

        #region OnCollectionChanged
        /// <summary>Raises the CollectionChanged event.</summary>
        protected void OnCollectionChanged()
        {
            if (CollectionChanged != null)
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
        #endregion OnCollectionChanged

        #region OnPropertyChanged
        /// <summary>Raises the PropertyChanged event.</summary>
        /// <param name="name">The name of the property for which the value has changed.</param>
        protected void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
        #endregion OnPropertyChanged

        #region Remove
        /// <summary>Removes a item from the collection.</summary>
        /// <param name="item">The item to be removed.</param>
        new public bool Remove(T item)
        {
            bool retVal = base.Remove(item);
            OnCollectionChanged();

            return retVal;
        }
        #endregion Remove

        #region RemoveAt
        /// <summary>Removes the item at a specific index from the collection.</summary>
        /// <param name="index">The index of the item to remove.</param>
        new public void RemoveAt(int index)
        {
            base.RemoveAt(index);
            OnCollectionChanged();
        }
        #endregion RemoveAt

        #endregion Methods
    }
}